package com.example.zyl.common.utils.http;


import org.apache.http.HttpResponse;
import org.apache.http.client.methods.*;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;

public class HttpUtils {

    private static final CloseableHttpClient httpClient = HttpClients.createDefault();

    /**
     * 发送GET请求
     *
     * @param url 请求的URL
     * @return 响应内容
     */
    public static String sendGet(String url) throws IOException {
        HttpGet getRequest = new HttpGet(url);
        return executeRequest(getRequest);
    }

    /**
     * 发送GET请求，并可设置请求头和查询参数
     *
     * @param baseUrl 基础URL
     * @param params  查询参数
     * @param headers 请求头
     * @return 响应内容
     */
    public static String sendGet(String baseUrl, Map<String, String> params, Map<String, String> headers) throws IOException {
        String urlWithParams = buildUrlWithParams(baseUrl, params);
        HttpGet getRequest = new HttpGet(urlWithParams);
        setHeaders(getRequest, headers);
        return executeRequest(getRequest);
    }

    /**
     * 发送POST请求
     *
     * @param url         请求的URL
     * @param jsonPayload 请求体
     * @return 响应内容
     */
    public static String sendPost(String url, String jsonPayload) throws IOException {
        HttpPost postRequest = new HttpPost(url);
        postRequest.setHeader("Content-Type", "application/json");
        postRequest.setEntity(new StringEntity(jsonPayload));
        return executeRequest(postRequest);
    }

    /**
     * 发送POST请求，并可设置请求头和表单参数
     *
     * @param url     请求的URL
     * @param params  表单参数
     * @param headers 请求头
     * @return 响应内容
     */
    public static String sendPost(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        HttpPost postRequest = new HttpPost(url);
        setHeaders(postRequest, headers);

        StringBuilder payload = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (payload.length() != 0) {
                payload.append("&");
            }
            payload.append(URLEncoder.encode(entry.getKey(), "UTF-8"));
            payload.append("=");
            payload.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }

        postRequest.setEntity(new StringEntity(payload.toString()));
        return executeRequest(postRequest);
    }

    /**
     * 发送PUT请求
     *
     * @param url         请求的URL
     * @param jsonPayload 请求体
     * @return 响应内容
     */
    public static String sendPut(String url, String jsonPayload) throws IOException {
        HttpPut putRequest = new HttpPut(url);
        putRequest.setHeader("Content-Type", "application/json");
        putRequest.setEntity(new StringEntity(jsonPayload));
        return executeRequest(putRequest);
    }

    /**
     * 发送DELETE请求
     *
     * @param url 请求的URL
     * @return 响应内容
     */
    public static String sendDelete(String url) throws IOException {
        HttpDelete deleteRequest = new HttpDelete(url);
        return executeRequest(deleteRequest);
    }

    /**
     * 发送DELETE请求，并可设置请求头
     *
     * @param url     请求的URL
     * @param headers 请求头
     * @return 响应内容
     */
    public static String sendDelete(String url, Map<String, String> headers) throws IOException {
        HttpDelete deleteRequest = new HttpDelete(url);
        setHeaders(deleteRequest, headers);
        return executeRequest(deleteRequest);
    }

    /**
     * 执行请求并返回响应内容
     *
     * @param request Http请求
     * @return 响应内容
     */
    private static String executeRequest(HttpUriRequest request) throws IOException {
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            return handleResponse(response);
        }
    }

    /**
     * 处理响应
     *
     * @param response HttpResponse对象
     * @return 响应内容
     */
    private static String handleResponse(HttpResponse response) throws IOException {
        int statusCode = response.getStatusLine().getStatusCode();
        if (statusCode >= 200 && statusCode < 300) {
            return EntityUtils.toString(response.getEntity());
        } else {
            throw new IOException("Unexpected response status: " + statusCode);
        }
    }

    /**
     * 设置请求头
     *
     * @param request 请求对象
     * @param headers 请求头映射
     */
    private static void setHeaders(HttpUriRequest request, Map<String, String> headers) {
        if (headers != null) {
            headers.forEach(request::setHeader);
        }
    }

    /**
     * 构建带有查询参数的URL
     *
     * @param baseUrl 基础URL
     * @param params  查询参数
     * @return 完整的URL
     */
    private static String buildUrlWithParams(String baseUrl, Map<String, String> params) throws UnsupportedEncodingException {
        StringBuilder urlWithParams = new StringBuilder(baseUrl);
        if (params != null && !params.isEmpty()) {
            urlWithParams.append("?").append(URLEncoder.encode(params.keySet().iterator().next(), "UTF-8")).append("=")
                    .append(URLEncoder.encode(params.values().iterator().next(), "UTF-8"));
            for (Map.Entry<String, String> entry : params.entrySet()) {
                if (entry.getKey().equals(params.keySet().iterator().next())) continue; // 已经添加了第一个参数
                urlWithParams.append("&").append(URLEncoder.encode(entry.getKey(), "UTF-8")).append("=")
                        .append(URLEncoder.encode(entry.getValue(), "UTF-8"));
            }
        }
        return urlWithParams.toString();
    }

}
